#include "stm32f10x.h"                  // Device header


/**
  * @brief  编码器初始化
  * @param  无
  * @retval 无
  */
void Encoder_Init(void)
{
	/*开启时钟*/
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);				//打开TIM3时钟，因为要使用TIM3的编码接口
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);			//打开GPIO时钟，因为要IO口输入正交信号
	
	/*GPIO初始化*/
	GPIO_InitTypeDef GPIO_Initstructure;							//初始化PA6，PA7为上拉输入
	GPIO_Initstructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_Initstructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;	
	GPIO_Initstructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_Initstructure);
	
	/*时基单元初始化*/
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitstructure;				//初始化编码器接口时基单元部分
	TIM_TimeBaseInitstructure.TIM_ClockDivision = TIM_CKD_DIV1;		//时钟滤波频率，用于决定滤波时钟（这里不重要）
	TIM_TimeBaseInitstructure.TIM_CounterMode = TIM_CounterMode_Up;	
	TIM_TimeBaseInitstructure.TIM_Period = 65536-1;					//给ARR最大值，防止溢出，同时方便读出数据得到负数
	TIM_TimeBaseInitstructure.TIM_Prescaler = 1-1;					
	TIM_TimeBaseInitstructure.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitstructure);
	
	/*输入捕获初始化*/
	TIM_ICInitTypeDef TIM_ICInitstructure;							//初始化输入捕获的滤波部分用于编码器接口（极性选择部分此处未设置，在TIM_EncoderInterfaceConfig函数进行初始化，避免重复设置）
	TIM_ICStructInit(&TIM_ICInitstructure);							//结构体初始化，若结构体没有完整赋值
																	//则最好执行此函数，给结构体所有成员都赋一个默认值	
																	//避免结构体初值不确定的问题	
	TIM_ICInitstructure.TIM_Channel = TIM_Channel_1;				//选择配置CH1（只有CH1,CH2能当编码器接口）
	TIM_ICInitstructure.TIM_ICFilter = 0xf;							//滤波设置，可以过滤信号抖动
	TIM_ICInit(TIM3,&TIM_ICInitstructure);
	TIM_ICInitstructure.TIM_Channel = TIM_Channel_2;				//选择配置CH2（只有CH1,CH2能当编码器接口）
	TIM_ICInitstructure.TIM_ICFilter = 0xf;							//滤波设置，可以过滤信号抖动
	TIM_ICInit(TIM3,&TIM_ICInitstructure);
	
	/*编码器接口配置*/				//TIM_EncoderMode_TI12配置编码器接口为两个通道输入边沿均有效。
	TIM_EncoderInterfaceConfig(TIM3,TIM_EncoderMode_TI12,TIM_ICPolarity_Falling,TIM_ICPolarity_Falling);
														//配置编码器模式以及两个输入通道是否反相
														//注意此时参数的Rising和Falling已经不代表上升沿和下降沿了，而是代表是否反相
	/*TIM使能*/													//此函数必须在输入捕获初始化之后进行，否则输入捕获的配置会覆盖此函数的部分配置
	TIM_Cmd(TIM3,ENABLE);											////使能TIM3，定时器开始运行
}

/**
  * @brief  获取编码器的增量值
  * @param  无
  * @retval 调用次函数后，返回编码器的增量值
  */
int16_t Encoder_Get(void)
{
	/*使用Temp变量作为中继，目的是返回CNT后将其清零*/
	int16_t Temp;
	Temp = TIM_GetCounter(TIM3);
	TIM_SetCounter(TIM3,0);
	return Temp;
}
